import L from 'leaflet';

/**
 * 地图交互工具类，支持鼠标样式、绘制线/面等操作
 */
export class DrawInteraction {
  private map: L.Map;
  private _tempLayer?: L.Layer;
  private _tempMarkers: L.CircleMarker[] = [];
  private _onClick?: (e: L.LeafletMouseEvent) => void;
  private _onContextMenu?: (e: L.LeafletMouseEvent) => void;

  constructor(map: L.Map) {
    this.map = map;
  }

  /**
   * 切换地图鼠标样式
   */
  public setMapCursor(cursor: string) {
    if (this.map) {
      const container = this.map.getContainer();
      container.style.cursor = cursor;
    }
  }

  /**
   * 关闭所有地图上的 click/contextmenu 临时绘制事件
   */
  public clearDrawEvents() {
    if (!this.map) return;
    if (this._onClick) {
      this.map.off('click', this._onClick);
      this._onClick = undefined;
    } else {
      this.map.off('click');
    }
    if (this._onContextMenu) {
      this.map.off('contextmenu', this._onContextMenu);
      this._onContextMenu = undefined;
    } else {
      this.map.off('contextmenu');
    }
  }

  /**
   * 启动绘制模式
   * @param mode marker | polyline | polygon
   * @param onDrawEnd 绘制完成回调
   */
  public startDrawMode(
    mode: 'marker' | 'polyline' | 'polygon',
    onDrawEnd: (points: L.LatLng[]) => void
  ) {
    if (!this.map) return;
    this.setMapCursor('crosshair');
    // 清除上一次的临时图形和事件
    if (this._tempLayer) {
      this.map.removeLayer(this._tempLayer);
      this._tempLayer = undefined;
    }
    if (this._tempMarkers) {
      this._tempMarkers.forEach(m => this.map?.removeLayer(m));
      this._tempMarkers = [];
    }
    this.clearDrawEvents();
    if (mode === 'marker') {
      this.map.once('click', (e: L.LeafletMouseEvent) => {
        const { lat, lng } = e.latlng;
        onDrawEnd([L.latLng(lat, lng)]);
        this.setMapCursor('');
      });
      return;
    }
    if (mode === 'polyline' || mode === 'polygon') {
      const points: L.LatLng[] = [];
      let tempShape: L.Polyline | L.Polygon | undefined;
      this._tempMarkers = [];
      const onClick = (e: L.LeafletMouseEvent) => {
        points.push(e.latlng);
        const marker = L.circleMarker(e.latlng, {
          radius: 5,
          color: mode === 'polyline' ? '#ff9800' : '#ff9800', 
          fillColor: '#ff1744', 
          fillOpacity: 1,
          weight: 2
        }).addTo(this.map!);
        this._tempMarkers.push(marker);
        if (tempShape) this.map?.removeLayer(tempShape);
        if (mode === 'polyline') {
          tempShape = L.polyline(points, { color: '#ff9800', dashArray: '4 4', weight: 2 }).addTo(this.map!);
        } else {
          tempShape = L.polygon(points, { color: '#ff9800', fillColor: '#ffe082', dashArray: '4 4', weight: 2 }).addTo(this.map!);
        }
        this._tempLayer = tempShape;
      };
      const onContextMenu = (e: L.LeafletMouseEvent) => {
        e.originalEvent.preventDefault();
        if ((mode === 'polyline' && points.length >= 2) || (mode === 'polygon' && points.length >= 3)) {
          onDrawEnd([...points]);
        }
        if (tempShape) this.map?.removeLayer(tempShape);
        if (this._tempMarkers) this._tempMarkers.forEach(m => this.map?.removeLayer(m));
        this._tempMarkers = [];
        this._tempLayer = undefined;
        this.map?.off('click', onClick);
        this.map?.off('contextmenu', onContextMenu);
        this.setMapCursor('');
      };
      this._onClick = onClick;
      this._onContextMenu = onContextMenu;
      this.map.on('click', this._onClick);
      this.map.on('contextmenu', this._onContextMenu);
    }
  }
}
